#pragma once
#include <iostream>
#include <cstring>
#include <vector>
#include <cstdint>

class MatrixMemView {
    size_t m_current_pos;
    size_t m_initial_pos;
    size_t m_stride_0;
    size_t m_stride_1;
    int32_t m_row_count;
    int32_t m_column_count;
    int32_t m_current_row;
    int32_t m_current_column;

public:
    MatrixMemView(void* init_pos, int32_t row_count, int32_t column_count, 
                  size_t stride_0, size_t stride_1);
    
    void setCoordinate(int32_t column, int32_t row);
    void* next(size_t step = 1);
    void moveToNextColumn(bool keep_row = false);
    void copyContinuousColumns(MatrixMemView& target, size_t step_length);
    void reinitialize();
    char checkCompatibility(const MatrixMemView& target) const;
    void copyTo(MatrixMemView& target, size_t length, int32_t data_size);
    
    template<typename DestinationType, typename SourceType>
    void assignTo(MatrixMemView& target, size_t length);
    
    void* getPointer() const { return reinterpret_cast<void*>(m_current_pos); }
    int32_t getColumnCount() const { return m_column_count; }
    int32_t getRowCount() const { return m_row_count; }
    int32_t getCurrentRow() const { return m_current_row; }
    int32_t getCurrentColumn() const { return m_current_column; }
};